package nacos_authoa.config;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import nacos_authoa.model.SysUserMsg;
import nacos_authoa.service.SysUserMsgService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.apache.shiro.session.Session;


import java.util.Collection;
import java.util.HashSet;
import java.util.List;

public class UserRealm extends AuthorizingRealm {



    @Autowired
    private SysUserMsgService sysUserMsgService;

    @Override
    public void setName(String name) {
        super.setName("userRealm");
    }

    /*授权*/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {

        System.out.println("已开启授权");
        SysUserMsg sysUserMsg =(SysUserMsg)principal.getPrimaryPrincipal();
        //查询数据库该用户所有的权限标识
        List<String> perms=sysUserMsgService.getPermsList(sysUserMsg.getId());

        SimpleAuthorizationInfo info =new SimpleAuthorizationInfo();
        //添加角色
//        info.addRole("admin");
        info.setStringPermissions(new HashSet<>(perms));
        return info;
    }


    /*认证*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("已开启认证");
        UsernamePasswordToken upToken=(UsernamePasswordToken)authenticationToken;
        String principal = (String)upToken.getPrincipal();
        System.out.println("upToken.getPrincipal()=====>"+principal);
        String username = upToken.getUsername();
        System.out.println("upToken.getUsername()====>"+username);
        Object principal1 = authenticationToken.getPrincipal();
        System.out.println("authenticationToken.getPrincipal()====>"+principal1);

        char[] chars = upToken.getPassword();
        String password = String.valueOf(chars);

        //数据库查询的正确名字和密码
        SysUserMsg userMsg = sysUserMsgService.getOne(new LambdaQueryWrapper<SysUserMsg>()
                .eq(SysUserMsg::getUsername, username));
        if (StringUtils.isEmpty(userMsg)){
            throw new UnknownAccountException();
        }
        if (!password.equals(userMsg.getPassword())){
           throw new IncorrectCredentialsException();
        }

        //单用户登录
        //处理session
        DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
        SessionManager sessionManager = (SessionManager) securityManager.getSessionManager();
        //获取当前已登录的用户session列表
        Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();
        SysUserMsg temp;
        for(Session session : sessions) {

            Object attribute = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
            if (attribute == null) {
                continue;
            }

            temp = (SysUserMsg) ((SimplePrincipalCollection) attribute).getPrimaryPrincipal();
            System.out.println("当前已登录的用户user: "+temp.toString());
            //清除该用户以前登录时保存的session，强制退出
            if (upToken.getUsername().equals(temp.getUsername())) {
                sessionManager.getSessionDAO().delete(session);
            }
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userMsg,password,getName());
        return info;


    }


    /**
     * 管理员授权
     * @param principals
     * @param permission
     * @return
     */
    @Override
    public  boolean isPermitted(PrincipalCollection principals, String permission){
        SysUserMsg user = (SysUserMsg) principals.getPrimaryPrincipal();
        return isAdmin(user)||super.isPermitted(principals,permission);
    }
    @Override
    public boolean hasRole(PrincipalCollection principals, String roleIdentifier) {
        SysUserMsg user = (SysUserMsg)principals.getPrimaryPrincipal();
        return isAdmin(user)||super.hasRole(principals,roleIdentifier);
    }

    public boolean isAdmin( SysUserMsg user) {
        return "admin".equals(user.getRoleName());
    }


    /**
     * 重写方法,清除当前用户的的 授权缓存
     * @param principals
     */
    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    /**
     * 重写方法，清除当前用户的 认证缓存
     * @param principals
     */
    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    /**
     * 自定义方法：清除所有 授权缓存
     */
    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    /**
     * 自定义方法：清除所有 认证缓存
     */
    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    /**
     * 自定义方法：清除所有的  认证缓存  和 授权缓存
     */
    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }


}
